<html>
<head><meta charset="utf-8"><title>UnsafeCells as raw pointers · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html">UnsafeCells as raw pointers</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="225809315"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/225809315" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#225809315">(Feb 10 2021 at 09:04)</a>:</h4>
<p>Would it be correct to say that all types with interior mutability could be implemented without using <code>UnsafeCell</code>, but using raw pointers to heap-allocated values? As far as I understand, the <code>noalias</code> and <code>readonly</code> LLVM attributes are not generated for types containing raw pointers.</p>



<a name="225967740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/225967740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#225967740">(Feb 11 2021 at 09:46)</a>:</h4>
<p>Here is an example of what I mean: <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=700cc3914a8ad527d9ee3a769934d5d1">playground</a>. It's a user-defined type with interior mutability that doesn't (directly) use <code>UnsafeCell</code>.</p>



<a name="225967748"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/225967748" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#225967748">(Feb 11 2021 at 09:46)</a>:</h4>
<p>Maybe an UnsafeCell is actually used in the implementation of <code>Box</code> or <code>std::alloc</code>? I'm not sure about that.</p>



<a name="225968308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/225968308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#225968308">(Feb 11 2021 at 09:53)</a>:</h4>
<p>In particular, the documentation of <code>UnsafeCell</code> says that "it's the only legal way to obtain aliasable data that is considered mutable". However, the example that I linked doesn't use an unsafe cell and seems a valid type with interior mutability. Does the example have UB for some reason? If not, the sentence from the documentation would be incorrect.</p>



<a name="225971125"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/225971125" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#225971125">(Feb 11 2021 at 10:21)</a>:</h4>
<p><span class="user-mention" data-user-id="116427">@Federico Poli</span> Your example is not interior mutability. The data is stored on the heap and not directly inside the <code>MyUnsafeCell</code>. <code>UnsafeCell</code> stores the data directly inside itself.</p>



<a name="225977866"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/225977866" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#225977866">(Feb 11 2021 at 11:35)</a>:</h4>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> thanks, that fully answers my question. I was thinking that interior mutability is a property of the API.</p>



<a name="226126537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226126537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226126537">(Feb 12 2021 at 11:45)</a>:</h4>
<p>Yeah, <code>UnsafeCell</code> exists to counteract / disable the immutability assumption that Rust makes when it sees a shared reference to some type / memory; obviously this assumption cannot go through raw pointers, so indeed with indirection you can make sure you never derive a mutable pointer to a <code>T</code> that derived from a shared reference to it or to a direct container. But without such "raw indirection", from a <code>self: &amp;'lt InlineWrapper&lt;T&gt;</code>, Rust will assume that the inner <code>T</code> is also aliased (<code>&amp;'lt T</code>) and that it is thus immutable. At that point any then-derived raw pointers to the <code>T</code> will no longer have the "capability" / be allowed to be used to mutate the <code>T</code> (read-only provenance). That's when wrapping the <code>T</code> in an <code>UnsafeCell</code> is necessary.</p>



<a name="226242814"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226242814" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226242814">(Feb 13 2021 at 12:28)</a>:</h4>
<p><span class="user-mention" data-user-id="116427">@Federico Poli</span> another way to put this is that your code doesn't create "shared references to mutable data", and thus it does not need <code>UnsafeCell</code></p>



<a name="226242830"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226242830" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226242830">(Feb 13 2021 at 12:29)</a>:</h4>
<p>however, that wording in the UnsafeCell docs does seem suboptimal to me. I'd have said something more like "it's the only legal way to obtain shared references to data that might be mutated", or "it's the only legal way to mutate data that is also pointed to by shared references". <span class="user-mention" data-user-id="133247">@bjorn3</span> <span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> what do you think?</p>



<a name="226244374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226244374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226244374">(Feb 13 2021 at 13:10)</a>:</h4>
<p>Explicitly mentioning shared references makes sense to me <span aria-label="+1" class="emoji emoji-1f44d" role="img" title="+1">:+1:</span> ; in that case I'd favor the former phrasing given that the latter is a bit more ambiguous w.r.t. provenance</p>



<a name="226245043"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226245043" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226245043">(Feb 13 2021 at 13:29)</a>:</h4>
<p>the thing is that UnsafeCell isnt the thing that lets you obtain the shared ref</p>



<a name="226245046"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226245046" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226245046">(Feb 13 2021 at 13:29)</a>:</h4>
<p>so "only legal way to obtain" sounds weird</p>



<a name="226245049"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226245049" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226245049">(Feb 13 2021 at 13:29)</a>:</h4>
<p>UnsafeCell is the thing that lets you mutate</p>



<a name="226276323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226276323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226276323">(Feb 14 2021 at 00:04)</a>:</h4>
<p>I see what you mean now <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span> <em>it's the only legal way to avoid disallowing mutation of data that is pointed to by a shared reference</em> ? The singular of <em>shared reference</em> seems to be important, otherwise people may think of "mutation through a <code>&amp;</code> is fine provided there is only one", and the double negative, while complex, is the one that better conveys the right nuance; in case people find it confusing, it also conveys that they need to think about that very nuance (especially with the following paragraphs in the docs detailing this stuff).</p>
<p>I'd even go as far as adding a footnote on that <em>shared reference</em> to add: <em>(or an active pointer derived from it)</em></p>
<p>But if all this is too much, then let's go for your second phrasing (but with a singular <em>shared reference</em>).</p>



<a name="226362318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226362318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226362318">(Feb 15 2021 at 09:43)</a>:</h4>
<p>To me, "<em>interior</em> mutability" risks to be confused with "mutability of the <em>internal state</em>", which is wrong when you store the state behind raw pointers. It might be worth clarifying this, as I had to read the compiler's source code to get it.</p>



<a name="226362844"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226362844" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226362844">(Feb 15 2021 at 09:48)</a>:</h4>
<p>What about <em>UnsafeCell is the only Rust type for which it's legal to mutate its content even while the unsafe cell is pointed by a shared reference</em>? I'm still unsatisfied with "content" because it's not clear that raw pointers shouldn't be followed.</p>



<a name="226363829"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/226363829" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Federico Poli <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#226363829">(Feb 15 2021 at 09:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers/near/226242814">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="116427">Federico Poli</span> another way to put this is that your code doesn't create "shared references to mutable data", and thus it does not need <code>UnsafeCell</code></p>
</blockquote>
<p>I see, yes. It creates "shared references to immutable data that points to mutable data".</p>



<a name="227178442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells%20as%20raw%20pointers/near/227178442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers.html#227178442">(Feb 21 2021 at 16:28)</a>:</h4>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> <span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> <span class="user-mention" data-user-id="116427">@Federico Poli</span> I thought about this some more and read the rest of the UnsafeCell docs and made a PR: <a href="https://github.com/rust-lang/rust/pull/82372">https://github.com/rust-lang/rust/pull/82372</a>. Feedback welcome!</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>